import logging
from typing import Type, Optional, List, Union
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from sqlalchemy import update, delete
from sqlalchemy.exc import SQLAlchemyError

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# --------------------- CREATE ---------------------
async def CreateRecord(
        db: AsyncSession,
        model: Type,
        data: dict,
        return_obj: bool = False
    ) -> tuple[Optional[Union[int, object]],Optional[Exception]]:
    """
    创建记录
        :param db: AsyncSession
        :param model: 模型类
        :param data: 字典数据
        :param return_obj: True返回完整对象，False返回ID
    """
    try:
        if not data:
            logger.warning("CreateRecord: data为空，插入失败")
            return None, ValueError("data为空")

        record = model(**data)
        db.add(record)
        await db.commit()
        await db.refresh(record)
        logger.info(f"CreateRecord ✅ 插入成功: {getattr(record, 'id', None)}")
        return (record if return_obj else getattr(record, 'id', None)), None
    except SQLAlchemyError as e:
        await db.rollback()
        logger.error(f"CreateRecord ❌ 插入失败: {e}")
        return None, e

# --------------------- READ (单条) ---------------------
async def GetRecordById(db: AsyncSession, model: Type, record_id: Union[int, str]):
    """
    根据ID查询单条记录
    """
    try:
        if record_id is None:
            logger.warning("GetRecordById: record_id为空")
            return None

        result = await db.execute(select(model).where(model.id == record_id))
        record = result.scalar_one_or_none()
        return record
    except SQLAlchemyError as e:
        logger.error(f"GetRecordById ❌ 查询失败: {e}")
        return None

# --------------------- READ (列表，可筛选) ---------------------
async def GetRecordsList(
    db: AsyncSession,
    model: Type,
    filter_field: Optional[str] = None,
    filter_value: Optional[Union[int, str]] = None
) -> List:
    """
    查询记录列表，可根据字段筛选
    """
    try:
        stmt = select(model)
        if filter_field is not None and filter_value is not None:
            if hasattr(model, filter_field):
                stmt = stmt.where(getattr(model, filter_field) == filter_value)
            else:
                logger.warning(f"GetRecordsList: 模型没有字段 '{filter_field}'，忽略筛选条件")
        result = await db.execute(stmt)
        return result.scalars().all()
    except SQLAlchemyError as e:
        logger.error(f"GetRecordsList ❌ 查询失败: {e}")
        return []

# --------------------- UPDATE ---------------------
async def UpdateRecordById(
    db: AsyncSession, model: Type, record_id: Union[int, str], update_data: dict
) -> int:
    """
    更新记录
    :return: 受影响行数
    """
    try:
        if not update_data:
            logger.warning("UpdateRecordById: update_data为空，更新失败")
            return 0

        stmt = (
            update(model)
            .where(model.id == record_id)
            .values(**update_data)
            .execution_options(synchronize_session="fetch")
        )
        result = await db.execute(stmt)
        await db.commit()
        rowcount = result.rowcount or 0
        logger.info(f"UpdateRecordById ✅ 更新完成，影响行数: {rowcount}")
        return rowcount
    except SQLAlchemyError as e:
        await db.rollback()
        logger.error(f"UpdateRecordById ❌ 更新失败: {e}")
        return 0

# --------------------- DELETE ---------------------
async def DeleteRecordById(# 这个是根据id删除的,上层的建筑需要改动,id唯一主键操作
    db: AsyncSession, model: Type, record_id: Union[int, str]
) -> int:
    """
    删除记录
    :return: 受影响行数
    """
    try:
        stmt = delete(model).where(model.id == record_id)
        result = await db.execute(stmt)
        await db.commit()
        rowcount = result.rowcount or 0
        logger.info(f"DeleteRecordById ✅ 删除完成，影响行数: {rowcount}")
        return rowcount
    except SQLAlchemyError as e:
        await db.rollback()
        logger.error(f"DeleteRecordById ❌ 删除失败: {e}")
        return 0
